package main

import (
	"flag"
	"log"
	"os"
	"strings"

	ctrl "ginbase/controller"
	"ginbase/switcher/comm"
	swtest "ginbase/switcher/test"
	swtimer "ginbase/switcher/timer"
	"ginbase/zConfig"
	// ue "ginbase/ueditor"
	// upload "ginbase/upload"
)

// 常量
const (
    // MainFileFolderName main.go文件夹名称
    MainFileFolderName = "cmd"
)

// Rtn 返回参数
type Rtn struct {
    Success bool        `json:"success"`
    Errmsg  string      `json:"errmsg"`
    Data    interface{} `json:"data"`
}

// 是否开启测试函数的开关 开发时使用 正式环境应该用不到
var test bool
// 是否开启定时任务的开关
var cron bool
// 配置文件的文件路径+文件名
var cfgfile string
// 指定服务运行的端口号
var port int

// 配置信息
var cfg *zConfig.ServiceConfig
// 常量定义
var consts map[string]string

func main() {
    log.SetFlags(log.LstdFlags | log.Lshortfile)
    var err error
    // 读取命令行参数
    flag.BoolVar(&test, "t", false, "test flag")
    flag.BoolVar(&cron, "c", false, "定时任务开关")
    flag.StringVar(&cfgfile, "config", "./config/config.yaml", "指定配置文件")
    flag.IntVar(&port, "p", 0, "指定服务运行的端口号,只生效在http服务中,优先级高于配置文件中的端口号")
    flag.Parse()

    // 程序运行的当前路径
    currentPath, _ := os.Getwd()
    // 根据程序运行的位置调整配置文件的相对路径 保证在cmd文件夹中go run的时候可以访问到配置文件
    if strings.Index(currentPath, MainFileFolderName) >= 0 {
        cfgfile = ".." + cfgfile[strings.Index(cfgfile, "/"):]
    }
    log.Printf("定位到配置文件路径:%s", cfgfile)

    // 读取服务配置
    cfg, err = zConfig.NewServiceConfig(cfgfile)
    dealError(err, "配置文件出错")
    // 读取配置文件中的常量
    consts = cfg.Configs
    comm.ConstVar = cfg.Configs
    // 单独设置了端口号
    if port != 0 {
        // 判断单独设置的端口号是否与配置文件中的端口号重复
        for _, httpPort := range cfg.HTTP.Port {
            // 是否与配置文件中的http服务端口号重复
            if httpPort == port {
                log.Printf("-p %d 与配置文件中http服务的端口号%d重复 不做任何操作", port, httpPort)
                break
            }
        }
        for _, httpsPort := range cfg.HTTPS.Port {
            // 是否与配置文件中的https服务端口号重复
            if httpsPort == port {
                log.Fatalf("-p %d 与配置文件中https的端口号%d冲突 请重新指定端口号再运行程序", port, httpsPort)
            }
        }
        // 改写需要生效的端口号为单独设置的端口号
        cfg.HTTP.Port = []int{port}
    }
    // 新建CTRLXorm结构体
    controller := ctrl.NewCTRLXorm(cfg, consts)
    if !test && !cron {
        // 开启服务
        controller.Server(cfg)
    } else {
        // 连接数据库
        engine := ctrl.ConnectEngine(cfg.Database, "default")
        // 异常情况处理
        defer controller.PanicHanlderII(nil, engine)
        if cron {
            // 定时任务
            swtimer.TimerEntry(engine)
        } else if test {
            // 测试代码
            swtest.TestEntry(engine)
        }
    }
}

// main函数中出错  打印错误信息并退出
func dealError(err error, msg string) {
    if nil != err {
        log.Println(msg)
        log.Fatal(err)
    }
}
